<?php

namespace App\Common\Lib;

use App\Common as com;
use App\Common\Lib\Lock as nameLock;

class Lock extends com\Lib\LibBase {

	private string $_lockKey;
	private com\Lib\Cache\KeyDB $_lockKeyDb;

	/**
	 * 锁名
	 * @param string $lockKey
	 */
	public function __construct( string $lockKey ) {
		$this->_lockKey = $lockKey;
		//
		$this->_lockKeyDb = com\Lib\Cache\KeyDB::use( '#sys.lock.' . $lockKey );
		//
		parent::__construct();
	}

	public function getLockKey(  ):string {
		return $this->_lockKey;
	}

	/**
	 * 获取锁keydb
	 * @return com\Lib\Cache\KeyDB
	 */
	private function getLockKeyDb(  ):com\Lib\Cache\KeyDB {
		return $this->_lockKeyDb;
	}

	/**
	 * 是否已上锁
	 * @return bool
	 */
	public function isLock(  ):bool {
		return $this->getLockKeyDb()->has();
	}

	/**
	 * 上锁
	 * @todo 上锁过程有bug，可以考虑用incr
	 * @param int|null $lockExpire 锁过期时间，单位：秒。[null]永久 [int]必须大于0
	 * @return bool
	 */
	public function lock( int $lockExpire ):bool {
		if( $this->isLock() ){
			return false;
		}
		//
		$this->getLockKeyDb()->set( 1, $lockExpire );
		//
		return true;
	}

	/**
	 * 上锁（等待）
	 * @param int|null $lockExpire 锁过期时间，单位：秒。[null]永久 [int]必须大于0
	 * @param int|null $waitTimeout 等待超时时间 [null]永久
	 * @return bool
	 */
	/*
	public function lockOrWait( int $lockExpire, int $waitTimeout = 15000 ):bool {
		while( $this->isLock() ){

		}
		if( $this->isLock() ){
			return false;
		}
		//
		$this->getLockKeyDb()->set( 1, $lockExpire );
		//
		return true;
	}
	*/

	/**
	 * 解锁
	 * @return void
	 */
	public function unlock(  ):void {
		$this->getLockKeyDb()->del();
	}

	// ===============================
	//
	//
	// 下面为静态方法
	//
	//
	// ===============================

	public static function new( string $lockKey ):self {
		return new static( $lockKey );
	}

	/**
	 * @param string $lockKey 锁名称
	 * @return $this
	 */
	public static function makeOfNew( string $lockKey ):self {
	    return self::make( ...func_get_args() );
	}

}
